URL:Introduction - Vue.js

注意

所演示的示例,都是在JS中将Vue实例绑定至HTML中的指定元素,然后再通过Vue实例中data内的属性或者methods中的方法,来对所绑定元素的子元素进行操作的,而不是对指定ID元素本身进行操作。

<div id="app">
    {{ message }}
</div>

有时候代码正常,但是Vue会报如下的错误,可能是因为在HTML页面中,JS脚本的载入在HTML页面的渲染之前执行了,解决方法就是把相关的script标签移动至body标签内最后的部分。

[Vue warn]: Cannot find element: #element-id

声明式渲染 - Declarative Rendering

简单的文本渲染

在HTML的元素内写上{{ message }},然后在JS中为data内的message属性指定值,即可显示所指定的文本,这是最基础的显示文本的方式。

在JS中,el用于定位HTML元素,Vue实例中的message属性与HTML中的字段同名,其值则会被渲染在最终的HTML页面中。

如果在控制台中手动更改app1.message的值,则能够看到HTML页面中显示的文本也会即时更新。

<div id="app1">
    {{ message }}
</div>
var app1 = new Vue({
    el: '#app1',
    data: {
        message: 'Hello Vue!'
    }
})

HTML元素属性绑定

在HTML中,通过v-bind这个指令来绑定至元素的指定属性,如v-bind:title就会将Vue实例绑定至HTML元素的title属性上。

v-前缀的指令用于对所渲染的DOM执行响应式操作。

下面的代码实现的效果是:当鼠标悬浮至span元素所显示的文本上时,就会显示JS中message的值,即:

'You loaded this page on ' + new Date()

<div id="app2">
    <span v-bind:title="message">
        Hover your mouse over me for a few seconds to see my dynamically bound title!
    </span>
</div>
var app2 = new Vue({
    el: '#app2',
    data: {
        message: 'You loaded this page on ' + new Date()
    }
})

如果用下面第一行的写法,那么最终渲染出来的HTML源代码则为第二行中的样子,而不是期望中的:将innerHTML属性绑定至message字段即可显示指定的文本。

<div v-bind:innerHTML="message"></div> // original code
<div innerHTML="Hello Vue"></div> // rendered content

条件判断与循环

条件判断

Vue不仅可以将数据绑定至属性,还能够绑定到DOM的结构上。

通过设置Vue实例中任意属性值为true或者false,可以生成或删除该元素。

查看最终的HTML源代码可知,Vue删除元素并不是更改其display属性,而是直接将整个HTML元素替换为<!---->这段字符串,这样更安全,用户将无法通过查看源代码的方式来拿到元素原本的内容。

<div id="app3">
    <p v-if="seen">Now you see me :)</p>
</div>
var app3 = new Vue({
    el: '#app3',
    data: {
        seen: true
    }
})

循环

v-for指令用于循环遍历数组中的元素。

在下面的示例中,Vue实例的todos属性包含三个元素,元素字段名为text,字段值为字符串。

而在HTML页面中,在ol之内的li元素只需写一个。通过v-for指令,能够根据Vue实例中对应属性里的元素个数,直接生成指定个li元素,其中不包含HTML原始代码里的那个li元素。

对于每个生成的li元素,设置其文本为所绑定todos属性中所对应的text字段的值。即第一个li元素的值,为todos属性中第一个text字段的值,第二个li元素的值为第二个text字段的值,以此类推。

<div id="app-4">
    <ol>
        <li v-for="todo in todos">
            {{ todo.text }}
        </li>
    </ol>
</div>
var app4 = new Vue({
    el: '#app-4',
    data: {
        todos: [
            { text: 'Learn JavaScript' },
            { text: 'Learn Vue' },
            { text: 'Build something awesome' }
        ]
    }
})

app4.todos.push({ text: 'You made it!'})语句会在app4这个Vue实例的todos属性的最后再添加一个text字段。

处理用户输入

调用函数

v-on指令用于绑定事件监听至指定的HTML元素上,这样可以调用所关联的Vue实例中的方法。

在下面的示例中,通过Vue实例中的reverseMessage方法,来将message属性中的文本逆序排列。

<div id="app-5">
    <p>{{ message }}</p>
    <button v-on:click="reverseMessage">Reverse Message</button>
</div>
var app5 = new Vue({
    el: '#app-5',
    data: {
        message: 'Hello Vue!'
    },
    methods: {
        reverseMessage: function () {
            this.message = this.message.split('').reverse().join('')
        }
    }
})

双向数据绑定

v-model实现双向数据绑定的效果。

在下面的示例中,v-model="message"实现对message的双向绑定。

input控件中输入的内容会同步更新至p元素。

但是!p元素的内容被更改之后,input控件中的内容并不会同步更新。(那应该如何理解这个双向数据绑定呢?)

<div id="app-6">
    <p>{{ message }}</p>
    <input type="text" v-model="message">
</div>
var app6 = new Vue({
    el: '#app-6',
    data: {
        message: 'Hello Vue!'
    }
})

组件系统

在Vue中,组件 - Component,是一个非常重要的概念。

编写大型应用时,很多地方是通用的,可以划分为若干个体积小的、自包含的(啥意思?)、可重用的组件。比如以列表形式展示内容的模块,就可以编写为一个大组件,而列表中的每个内容,又是一个小组件。

本质上,Vue中的组件就是一个带预定义设置的Vue实例。下面的代码示范了如何注册一个Vue组件:

Vue.component('todo-item', {
    template: '<li>This is a todo</li>'
})

注册完组件之后,在HTML中,就可以用下面的方式创建一个组件的实例:

<ol>
    <todo-item></todo-item>
</ol>

但是以上面的方式来简单地定义一个组件的话,如果创建多个组件的实例,生成的文本都是相同的。为了让各个组件有不同的内容,可以通过props属性,来将父级域的值,传递给子组件。

Vue.component('todo-item', {
    props: ['todo'],
    template: '<li>{{ todo.text }}</li>'
})

然后就可以通过v-bind指令,在HTML中将父元素的值传递给各个子组件。

下面的代码,在HTML中遍历Vue实例中groceryList属性里的每一项item,并将每个itemtodo绑定。

而在定义组件的JS代码中,接收传入的todo,并在li元素中显示todo中的字符串。

// 定义Vue组件todo-item
// 组件中通过名为todo的props属性
// 来从父级域向子组件中传递数据
// 下面的代码即是将传递给todo属性的text字段渲染至'li'元素中
Vue.component('todo-item', {
    props: ['todo'],
    template: '<li>{{ todo.text }}</li>'
}

// Vue实例中定义属性数组groceryList
new Vue({
    ...
    data: {
        groceryList: [
            { text: '...' },
            { text: '...' },
            { text: '...' }
        ]
    }
})

// HTML中创建todo-item组件
// 遍历属性数组groceryList中的每一项item
// 并将其与todo绑定
// 如此便可将每个todo中的数据传至各个组件中
<todo-item v-for="item in groceryList" v-bind:todo="item">

再总结一下上面的例子:

  1. 在Vue实例中定义属性数组,数组中的元素用于在前端页面上以有序列表形式显示;

  2. 定义Vue组件,设置好所绑定的props属性的名称,以及Vue实例中属性数组元素的显示格式;

  3. 在前端HTML页面中,写一个组件,用v-for遍历属性数组,并用v-bind将实例中的数据传递给前台。


samsara0511
932 声望729 粉丝